/**
 * @file Session.h
 * @author huangxiaozhu (xiaozhuhuang2014@163.com)
 * @brief  Session基类
 * @version 1.0.0
 * @date 2024-02-26
 * 
 * @copyright Copyright (c) 2024
 * 
 */


#pragma once

#include <iostream>
#include <memory>
#include <boost/asio.hpp>
#include <functional>
#include <string>

using boost::asio::ip::tcp;

class Session;      // 前置声明
using SessionPtr = std::shared_ptr<Session>;

// socketPtr指针
using TcpSocketPtr = std::shared_ptr<tcp::socket>;

// 用于创建Session对象的函数，方便子类对象注册到TcpServer中
template <typename SessionT>
SessionPtr NewSessionObjFunc(TcpSocketPtr socket)
{
    if (std::is_base_of<Session, SessionT>::value)
    {
        std::cout << "Create SessionObj, type_name:" << typeid(SessionT).name() << std::endl;
        return std::make_shared<SessionT>(socket);
    }
    std::cout << "Create SessionObj  return nullptr" << std::endl;
    return nullptr;
}

using SessionCloseCallback = std::function<void(const std::string&)>;   // 客户端关闭回调,主要是让TcpServer知道客户端关闭了
using CreateSessionObjFunc = std::function<SessionPtr(TcpSocketPtr)>;   // 创建Session对象函数


// Seesion作为收发数据的基类
class Session : public std::enable_shared_from_this<Session> 
{
public:
    Session(std::shared_ptr<tcp::socket> socket);
    virtual ~Session();

    virtual void Start();
    virtual void Stop();

    std::string GetName();
    void SetCloseCallback(const SessionCloseCallback& callback);
    void OnCloseSession();

    void Recv();
    void Send(const std::string& message);

    virtual void OnRecv(const char* bufData, size_t len);

private:
    std::shared_ptr<tcp::socket> m_socket;
    enum { MAX_LENGTH = 1024 };
    char m_data[MAX_LENGTH] = {0};

    std::string m_name;
    SessionCloseCallback m_closeCallback = nullptr;
    bool m_isRunning = false;
};

